#ifndef _BUFFER_PROXY_H
#define _BUFFER_PROXY_H
#include <iostream>
#include <mutex>
#include <list>
#include <vector>
#include "BufferNotifier.h"

typedef int (*usrCb)(void *frame, void *usr_data);
class BufferNotifier;

typedef struct _usrFrame
{
    int frame_id;
    void *frame_data;
    void *usr_data;
    usrCb release_cb;
    int ref_cnt;
}usrFrame;

class BufferListener {
public:
    BufferListener();
    ~BufferListener();
    virtual void dataCallback(const void *data) = 0;
};

class Importer
{
public:
    Importer();
    ~Importer();
    int InputFrame(void* frame_data);
    void addListener(BufferListener *listener);
    int removeListener(int listener_id);
    int releaseFrame(int frame_id);
    virtual int onReleaseData(void* frame_data) = 0;
public:
    static int releaseData(void *frame, void *usr_data);
private:
    BufferNotifier* mNotifier;
};

typedef struct BufferListenerProxy
{
    int listener_id;
    BufferListener* listener;
}BufferListenerProxy;

class BufferNotifier {
public:
    static BufferNotifier *getInstance();
    ~BufferNotifier();
    int addFrame(void* frame_data, void *usr_data, usrCb release_cb);
    void increaseBufRef(usrFrame* frame);
    int releaseFrame(int frame_id);
    int addListener(BufferListener *listener);
    int removeListener(int listener_id);
    int onNotify(void* frame);

public:
    int getFrameCount() { return mFrameList.size(); };

private:
    BufferNotifier();

private:
    static BufferNotifier *mInstance;
    static std::mutex mInstanceMutex;
    std::mutex mListenerMutex;
    std::mutex mListMutex;
    std::list<usrFrame> mFrameList;
    std::vector<BufferListenerProxy> mFrameListener;
    int mFrameIdCount;
    int mListenerCount;
};
#endif
